<!-- 把 url 地址也给 表格,让表格去请求数据,并展示 -->

<!-- 更新:
  表格功能:

  传入 分页方法 格式( funcName(pageIndex:number,pageSize:number) ),以及后台 使用 SendPageData 方法响应数据 , 就可以享受 表格的自动生成

  自动生成 每个列的 slot 组件, 例如: name => <slot name="name" :value="scope.row"></slot>,通过 <template #name="row"> <CusBtnVue link @click="alert(row.value)"> 更新</CusBtnVue> </template> 调用 该插槽 (默认展示 列的内容)(需要 手动添加组件的方式,调用插槽)

  使用 operate 插槽 生成 表格 左侧列表,通过 <template #operate="row"></template> 调用 该插槽

  通过 传入 propName 对象{name:"医院名字"}的方式 , 实现 排序表格 中文列名生成列名字 是否隐藏 功能

  获取分页 防抖


  修复的异常:
  在表格 pageSize 20 => 60 pageIndex 6 => 2 的时候,会请求两次数据,造成表格渲染失败
  解决办法: 使用 axios 的取消请求 和 watchEffect 取消请求
    代价 就是需要调用 getPageAsync 方法 ,使 请求传入 signal: controller.signal,利用 watchEffect的onInvalidate() 的回调函数,将 请求取消
    const controller = new AbortController();
    axios.get('/foo/bar', {
      signal: controller.signal
    }).then(function(response) {
      //...
    });
    // 取消请求
    controller.abort()
 -->

<template>
  <!-- 展示每页的数据 -->
  <!-- {{ tableData.length }} -->
  <!-- 将 循环创建 el-table-column 的过程简化了亿点点 -->
  <ElTable
    v-loading="loading"
    :data="tableData"
    stripe
    @cell-click="cellClick"
    :cell-style="cellStyle"
    border
  >
    <!-- <ElTableColumn type="index" label="序号" width="55" align="center" fixed /> -->
    <!-- 当未填写 str[item] 的时候 使用 item(属性名) -->

    <!-- <template v-for="(item, index) in reflectionPopsName()" :key="index"> -->
    <!-- <ElTableColumn :label="itemName(item)" :prop="item" show-overflow-tooltip min-width="100"> -->
    <!-- <template #default="scope"> -->
    <!-- 将子组件的 row 数据,上抛出去 -->
    <!-- <slot :name="item" :row="scope.row"> -->
    <!-- 给插槽一个默认数据 -->
    <!-- {{ scope.row[item] }} -->
    <!-- </slot> -->
    <!-- </template> -->
    <!-- </ElTableColumn> -->
    <!-- </template> -->

    <!-- 当未填写 str[item] 的时候 使用 item(属性名) -->
    <template v-for="(item, index) in props.columns" :key="index">
      <ElTableColumn v-bind="item">
        <template v-if="item.type != 'index'" #default="scope">
          <div>
            <span
              v-if="
                !(editing && currentEditIndex === scope.$index && currentEditProp === item.prop)
              "
            >
              <!-- 将子组件的 row 数据,上抛出去 -->
              <slot :name="item" :row="scope.row">
                <!-- 给插槽一个默认数据 -->
                {{ scope.row[item.prop!] }}
              </slot>
            </span>

            <el-input
              v-else
              ref="editInputRef"
              size="small"
              v-model="scope.row[item.prop!]"
              @blur="finishEdit"
            ></el-input>
          </div>
        </template>
      </ElTableColumn>
    </template>
    <!-- 操作栏, 需要赋值 -->
    <slot name="operation" />
  </ElTable>
</template>

<script lang="ts" setup>
import { nextTick, ref, watchEffect } from 'vue'
import { type ICusTableColumn, CusColumn } from './CusTableType'

// 组件属性
const props = withDefaults(
  defineProps<{
    data: Array<object> // page 分页api
    // 确定表格的 name 如果不写,则直接使用 默认值(prop 的 name 值),需要将 表格所需要的全部列传递进来
    // propName?: KeyValuePropName | null
    // 表格的 列名
    columns?: Array<ICusTableColumn>
  }>(),
  {
    propName: null,
    columns: () => [],
  },
)

const emits = defineEmits(['getTableData'])
// 加载进度条
const loading = ref(false)
// 表格数据
const tableData = ref<Array<object>>([])

watchEffect(() => {
  tableData.value = props.data
})

//#region 编辑列

const editing = ref(false)
const currentEditIndex = ref<number | null>(null)
const currentEditProp = ref<string | null>(null)
// 为什么是一个数组形式的数据
const editInputRef = ref<Array<HTMLElement>>()

const cellClick = (
  row: object,
  column: { property: string },
  cell: HTMLTableCellElement,
  event: Event,
) => {
  const dataIndex = tableData.value.indexOf(row)
  const columnName = column.property
  if (
    editing.value &&
    (currentEditIndex.value !== dataIndex || currentEditProp.value !== columnName)
  ) {
    finishEdit()
  }
  if (
    !editing.value ||
    currentEditIndex.value !== dataIndex ||
    currentEditProp.value !== columnName
  ) {
    editing.value = true
    currentEditIndex.value = dataIndex
    currentEditProp.value = columnName
    nextTick(() => {
      editInputRef.value![0].focus()
    })
  }
}
const finishEdit = () => {
  editing.value = false
  currentEditIndex.value = null
  currentEditProp.value = null
  // 在这里你可以添加保存更改的逻辑
}

//#endregion

// 优化, 让组件变成, 传入组件字段/样式就能更换其想要的颜色
// {prop:"drug_name", value:"安师大", style:{ backgroundColor: 'rgba(80,227,194)', color: 'red' }}
type IterationType = { [key: string]: string }
const cellStyle = ({
  row,
  column,
  rowIndex,
  columnIndex,
}: {
  row: IterationType
  column: IterationType
  rowIndex: number
  columnIndex: number
}) => {
  // 列样式设置
  const columnStyles = [
    {
      prop: 'drug_name',
      value: '安师大',
      style: { backgroundColor: 'rgba(80,227,194)', color: 'red' },
    },
    {
      prop: 'drug_name',
      value: '■◎注射用硫酸长春新碱',
      style: { backgroundColor: 'rgba(80,100,194)', color: 'yellow' },
    },
  ]

  // 遍历 columnStyles 数组，找到匹配的 prop 和 value，返回对应的 style 对象
  for (const columnStyle of columnStyles) {
    if (columnStyle.prop === column.property && columnStyle.value === row[column.property]) {
      return columnStyle.style
    }
  }
}
</script>
